
open Ast

let rec sideEffects_list func strong = function
	| [] -> false
	| a::b -> if func strong a then true else sideEffects_list func strong b
	

let rec sideEffects_expression strong expr =
	sideEffects_list sideEffects_assignmentExpression strong expr

and sideEffects_assignmentExpression strong = function
	| ACondExpr expr -> sideEffects_conditionalExpression strong expr
	| AAssignOp _ -> true

and sideEffects_conditionalExpression strong = function
	| ACondBinaryExpr expr -> sideEffects_binaryExpression strong expr
	| ACondTernaryExpr (expr1,expr2,expr3) ->
		(sideEffects_binaryExpression strong expr1)
		|| (sideEffects_assignmentExpression strong expr2)
		|| (sideEffects_assignmentExpression strong expr3)

and sideEffects_binaryExpression strong = function
	| AUnaryExpr expr -> sideEffects_unaryExpression strong expr
	| ABinaryExpr (op,expr1, expr2) ->
		(sideEffects_binaryExpression strong expr1)
		|| (sideEffects_binaryExpression strong expr2)

and sideEffects_unaryExpression strong = function
	| APostfixExpr expr -> sideEffects_postfixExpression strong expr
	| AOpUnaryExpr (op, expr) ->
		(String.length op > 1)
		|| (sideEffects_unaryExpression strong expr)

and sideEffects_postfixExpression strong = function
	| ALeftHandSide lhs -> sideEffects_leftHandSideExpression strong lhs
	| ALeftHandSideOp _ -> true

and sideEffects_leftHandSideExpression strong = function
	| ANewExpression expr -> sideEffects_newExpression strong expr
	| ACallExpression _ -> true

and sideEffects_newExpression strong = function
	| AMemberExpression expr -> sideEffects_memberExpression strong expr
	| ANewMemberExpression _ -> true

and sideEffects_memberExpression strong = function
	| APrimaryExpr expr -> sideEffects_primaryExpression strong expr
	| AFunctionExpr _ -> strong
	| AMemberBracketExpr (expr1, expr2) -> 
		(sideEffects_memberExpression strong expr1)
		|| (sideEffects_expression strong expr2)
	| AMemberDotExpr (expr, ident) ->
		sideEffects_memberExpression strong expr
	| AMemberNewExpr _ -> true

and sideEffects_primaryExpression strong = function
	| AThis -> false
	| AIdentifier _ -> false
	| ALiteral _ -> false
	| AArrayLiteral literal -> sideEffects_arrayLiteral strong literal
	| AObjectLiteral literal -> sideEffects_objectLiteral strong literal
	| AExpression expr -> sideEffects_expression strong expr

and sideEffects_arrayLiteral strong = function
	| AElisions _ -> false
	| AElements elements -> sideEffects_list sideEffects_element strong elements
	| AElementsAndElisions (elements,_) -> sideEffects_list sideEffects_element strong elements

and sideEffects_element strong (_,expr) =
	sideEffects_assignmentExpression strong expr

and sideEffects_objectLiteral strong props =
	sideEffects_list sideEffects_propertyAssignment strong props

and sideEffects_propertyAssignment strong = function
	| APropAssignment (_,expr) -> sideEffects_assignmentExpression strong expr
	| APropGet _ -> strong
	| APropSet _ -> strong


